package com.refusea.train.domain.helper

import com.refusea.train.config.mvc.WebSession
import com.refusea.train.domain.cache.CourseCache
import com.refusea.train.domain.cache.UserCache
import com.refusea.train.domain.entity.Order
import com.refusea.train.domain.ex.BizEx
import com.refusea.train.domain.req.OrderReq
import com.refusea.train.domain.vo.PaginationVo
import com.refusea.train.mapper.OrderMapper
import org.springframework.stereotype.Component

/**
 * @author Zhang Yan 2024/4/4
 **/
@Component
class OrderHelper(
    private val orderMapper: OrderMapper,
    private val userCache: UserCache,
    private val courseCache: CourseCache,
) {

    private val limit = 10

    fun query(req: OrderReq): PaginationVo {

        req.schoolId = WebSession.user().schoolId
        req.calculateOffset(limit)
        req.end = req.end?.plusDays(1)

        val total = orderMapper.count(req)
        if (total == 0) {
            return PaginationVo.empty(req.page, limit)
        }

        return PaginationVo(
            req.page,
            limit,
            total,
            if (req.offset >= total) {
                emptyList()
            } else {
                val orders = orderMapper.query(req)
                orders.forEach {
                    it.course = courseCache.get(it.courseId)?.name
                    it.parent = userCache.get(it.parentId)?.name
                    it.student = if (it.studentId == it.parentId) {
                        null
                    } else {
                        userCache.get(it.studentId)?.name
                    }
                }
                orders
            }
        )
    }

    fun save(order: Order): Int {

        order.schoolId = WebSession.user().schoolId

        if (order.paid && !order.completed) {
            // the same student can only buy one course at the same time
            val orders = orderMapper.selectByCourseIdAndStudentId(order.schoolId, order.courseId, order.studentId)
            if (orders.any { it.paid && !it.completed }) {
                throw BizEx.of("该学员已经在学习该课程，不支持重复购买")
            }
        }

        if (order.id == 0) {
            orderMapper.insert(order)
        } else {
            orderMapper.update(order)
        }

        return order.id
    }

    fun markPaid(id: Int) {

        val order = orderMapper.select(id) ?: throw BizEx.of("订单不存在")

        val schoolId = WebSession.user().schoolId
        if (order.schoolId != schoolId) {
            throw BizEx.of("参数异常，请重新登录")
        }

        val orders = orderMapper.selectByCourseIdAndStudentId(schoolId, order.courseId, order.studentId)
        if (orders.any { it.paid && !it.completed }) {
            throw BizEx.of("该学员已经在学习该课程，不支持重复购买")
        }

        orderMapper.markPaid(id)
    }

}
